package com.moons.idevices.printers;

import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;
import android.util.Log;

import com.moons.idevices.IPrinter;
import com.moons.idevices.R;
import com.moons.idevices.model.Appointment;
import com.moons.idevices.model.Visitor;
import com.moons.idevices.utils.StatusDescribe;
import com.szsicod.print.escpos.PrinterAPI;
import com.szsicod.print.io.USBAPI;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

public class RT58C extends BasePrinter implements Printer {
    private final String TAG = this.getClass().getSimpleName();


    public RT58C(IPrinter iPrinter, Context context) {
        mIPrinter = iPrinter;
        mContext = context;
    }


    @Override
    public void connect() {

        if (PrinterAPI.getInstance().connect(new USBAPI(mContext)) == PrinterAPI.SUCCESS) {
            Log.d(TAG, "connected: ");

//            String stateStr = PrinterUtils.getPrinterStatus();

            if (mIPrinter != null) {

                mIPrinter.onConnected(isPrintFunctional());
                return;
            }

        }

        if (mIPrinter != null) {
            mIPrinter.onConnected(false);
        }

    }

    @Override
    public void disconnect() {
        PrinterAPI.getInstance().disconnect();
    }

    /**
     * 可以根据实际情况，判断什么情况下认为是不可用
     *
     * @return
     */
    @Override
    public boolean isPrintFunctional() {

        String status = StatusDescribe.getStatusDescribe(PrinterAPI.getInstance().getStatus());

        Log.w(TAG, "isPrintFunctional: " + status);

        return !StatusDescribe.isOffline()
                && !StatusDescribe.isOutOfPaper();

    }


    /**
     * 打印下划线
     */
    @Override
    public void printDividerLine() {

        underLineCharFont();
        try {
            PrinterAPI.getInstance().printString("                             ", "GBK", true);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void printAppointment(Appointment appointment, boolean isCut) {
        PrinterAPI.getInstance().init();
        PrinterAPI.getInstance().setLineSpace(50);
        printTitle(mContext.getString(R.string.appointment));
        printDividerLine();

        if (!TextUtils.isEmpty(appointment.getTips())) {

            printContent(String.format(mContext.getString(R.string.text_tips), appointment.getTips()));

        }


        if (!TextUtils.isEmpty(appointment.getName())) {

            printContent(String.format(mContext.getString(R.string.text_name), appointment.getName()));

        }


        if (!TextUtils.isEmpty(appointment.getShangHaiQRCode())) {

            printContent(String.format(mContext.getString(R.string.text_shanghai_qr_code), appointment.getShangHaiQRCode()));

        }

        if (!TextUtils.isEmpty(appointment.getTemperature())) {

            printContent(String.format(mContext.getString(R.string.text_tmperatur), appointment.getTemperature()));

        }

        if (!TextUtils.isEmpty(appointment.getDateAndTime())) {

            printContent(String.format(mContext.getString(R.string.text_date_time), appointment.getDateAndTime()));

        }

        if (appointment.isTempAuthorize()) {

            if (!TextUtils.isEmpty(appointment.getMatterOfVisit())) {

                printContent(String.format(mContext.getString(R.string.text_subject_matter_of_visit), appointment.getMatterOfVisit()));

            }

            if (!TextUtils.isEmpty(appointment.getTmpAuthorizer())) {

                printContent(String.format(mContext.getString(R.string.text_tmp_licensor), appointment.getTmpAuthorizer()));

            }

        } else {


            if (!TextUtils.isEmpty(appointment.getWorkOrder())) {

                printContent(String.format(mContext.getString(R.string.text_work_order), appointment.getWorkOrder()));

            }

            if (!TextUtils.isEmpty(appointment.getVisitorType())) {

                printContent(String.format(mContext.getString(R.string.text_visitor_type), appointment.getVisitorType()));

            }

        }
        if (!TextUtils.isEmpty(appointment.getQrcode())) {
            printContent(mContext.getString(R.string.text_qr_code));
            PrinterAPI.getInstance().setAlignMode(1);// 居中
            PrinterAPI.getInstance().printQRCode(appointment.getQrcode(), 8, false);

        }

        if (isCut) {

            fullCut();

        }
    }

    @Override
    public void printVisitor(Visitor visitor, boolean isCut) {
        PrinterAPI.getInstance().init();
        PrinterAPI.getInstance().setLineSpace(50);

        printTitle("访客信息");
        printDividerLine();
        if (!TextUtils.isEmpty(visitor.getName())) {
            printContent("访客姓名：" + visitor.getName());
        }
        if (!TextUtils.isEmpty(visitor.getCellPhoneNumber())) {
            printContent("手机号码：" + visitor.getCellPhoneNumber());
        }
        if (!TextUtils.isEmpty(visitor.getIdCardNumber())) {
            printContent("证件号：  " + visitor.getIdCardNumber());
        }
        if (!TextUtils.isEmpty(visitor.getType())) {
            printContent("访客类型：" + visitor.getType());
        }

        if (!TextUtils.isEmpty(visitor.getHealthCode())) {
            printContent("随申码：  " + visitor.getHealthCode());
        }
        if (!TextUtils.isEmpty(visitor.getTemp())) {
            printContent("体温：    " + visitor.getTemp());
        }
        if (isCut) {

            fullCut();

        }
    }

    private void fullCut() {
        PrinterAPI.getInstance().cutPaper(66, 0);
    }


    private static void underLineCharFont() {
        PrinterAPI.getInstance().setAlignMode(1);
        PrinterAPI.getInstance().setCharSize(0, 0);
        PrinterAPI.getInstance().setFontStyle(0, true, false, false, false);
        PrinterAPI.getInstance().setEnableUnderLine(1);
    }


    /**
     * 打印标题
     *
     * @param title
     */
    public static void printTitle(String title) {

        PrinterAPI.getInstance().setEnableUnderLine(0);
        PrinterAPI.getInstance().setAlignMode(1);
        PrinterAPI.getInstance().setCharSize(1, 1);
        PrinterAPI.getInstance().setFontStyle(1, false, true, true, true);
        try {
            PrinterAPI.getInstance().printString(title, "GBK", true);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


    }

    public static void printTips(String tips) {

        PrinterAPI.getInstance().setEnableUnderLine(0);
        PrinterAPI.getInstance().setAlignMode(0);
        PrinterAPI.getInstance().setCharSize(0, 0);
        PrinterAPI.getInstance().setFontStyle(0, false, false, false, false);

        try {
            PrinterAPI.getInstance().printString(tips, "GBK", true);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


    }
    public void printBlankLine() {


        printContent("\r\n");

    }

    /**
     * 打印内容
     *
     * @param content
     */
    public static void printContent(String content) {

        normalCharFont();
        try {
            PrinterAPI.getInstance().printString(content, "GBK", true);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


    }

    private static void normalCharFont() {
        PrinterAPI.getInstance().setEnableUnderLine(0);
        PrinterAPI.getInstance().setAlignMode(0);
        PrinterAPI.getInstance().setCharSize(0, 0);
        PrinterAPI.getInstance().setFontStyle(0, false, false, false, false);

    }

    /**
     * 打印文字
     *
     * @param text
     * @param iPrinter
     */
    @Override
    public void printText(String text, IPrinter iPrinter) {
        PrinterAPI.getInstance().init();
        PrinterAPI.getInstance().setAlignMode(0);
        PrinterAPI.getInstance().setLineSpace(50);
        try {
            int ret = PrinterAPI.getInstance().printString(text, "GBK", true);
            iPrinter.actionResult(ret == PrinterAPI.SUCCESS);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        printBlankLine();
        fullCut();
    }

    /**
     * 打印二维码
     *
     * @param qrText
     * @param iPrinter
     */
    @Override
    public void printQRCode(String qrText, IPrinter iPrinter) {
        PrinterAPI.getInstance().init();
        PrinterAPI.getInstance().setAlignMode(0);
        PrinterAPI.getInstance().setLineSpace(50);

        PrinterAPI.getInstance().setAlignMode(1);// 居中
        int ret = PrinterAPI.getInstance().printQRCode(qrText, 8, false);
        iPrinter.actionResult(ret == PrinterAPI.SUCCESS);
        printBlankLine();
        fullCut();
    }


    /**
     * 读取Assets的text文件
     *
     * @param fileName
     * @return
     */
    public static byte[] readAssetsText(AssetManager assetManager, String fileName) {
        try {
            InputStream inputStream = assetManager.open(fileName);
            byte[] buffer = new byte[inputStream.available()];
            List<Byte> byteList = new ArrayList<>();
            while (inputStream.read(buffer) != -1) {
                String string = new String(buffer);
                StringBuilder stringBuilder = new StringBuilder();

                stringBuilder.append(string);
                string = stringBuilder.toString();
                string = string.trim();
                string = string.replaceAll(" |,|\r|\n|#", "");
                if (string.length() % 2 != 0) {
                    string = string.substring(0, string.length() - 2);
                }
                byteList.addAll(hexStr2Str(string));
            }
            inputStream.close();
            byte[] bytes = new byte[byteList.size()];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = byteList.get(i);
            }
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 58mm打印机 商品打印样式
     * 样式：################# ++++ ---- ****(#名称 +单价 -数量 *总计)
     *
     * @param name   商品名称
     * @param price  商品单价 不能大于99.9元
     * @param number 商品数量 不能大于9999个
     * @param total  商品总计 不能大于99.9元
     * @return 返回商品打印样式。
     * -1 ：名称格式错误
     * -2 ：单价格式错误
     * -3 ：数量格式错误
     * -4 ：总计格式错误
     */
    public static String commodity58Print(String name, String price, String number, String total) {
        String printText = "";
        String takeUp = " ";                // 填充字符
        String nameStr = name;
        int nameLen = byteNum(nameStr);
        int priceLen = byteNum(price);
        int numberLen = byteNum(number);
        int totalLen = byteNum(total);
        if (nameLen < 17) {
            printText += nameStr;
            for (int i = 0; i < 17 - nameLen; i++)
                printText += takeUp;
            nameLen -= byteNum(nameStr);
        } else {
            printText += nameStr.substring(0, 8);
            printText += takeUp;
            nameLen -= byteNum(nameStr.substring(0, 8));
            nameStr = nameStr.substring(8, nameStr.length());
        }

        if (priceLen < 5) {
            for (int i = 0; i < 5 - priceLen; i++)
                printText += takeUp;
            printText += price;
        } else {
            return "-2";
        }

        if (numberLen < 5) {
            for (int i = 0; i < 5 - numberLen; i++)
                printText += takeUp;
            printText += number;
        } else {
            return "-3";
        }

        if (totalLen < 5) {
            for (int i = 0; i < 5 - totalLen; i++)
                printText += takeUp;
            printText += total;
        } else {
            return "-4";
        }
        printText += "\n";
        while (nameLen > 0) {
            if (nameLen > 16) {
                printText += nameStr.substring(0, 8);
                nameLen -= byteNum(nameStr.substring(0, 8));
                nameStr = nameStr.substring(8, nameStr.length());
            } else {
                printText += nameStr;
                nameLen -= byteNum(nameStr);
            }
            printText += "\n";
        }
        return printText;
    }

    /**
     * 80mm打印机 商品打印样式
     * 样式：######################## ++++++++ ---- ********(#名称 +单价 -数量 *总计)
     *
     * @param name   商品名称
     * @param price  商品单价 不能大于99999.99元
     * @param number 商品数量 不能大于9999个
     * @param total  商品总计 不能大于99999.99元
     * @return 返回商品打印样式。
     * -1 ：名称格式错误
     * -2 ：单价格式错误
     * -3 ：数量格式错误
     * -4 ：总计格式错误
     */
    public static String commodity80Print(String name, String price, String number, String total) {
        String printText = "";
        String takeUp = " ";                // 填充字符
        String nameStr = name;
        int nameLen = byteNum(nameStr);
        int priceLen = byteNum(price);
        int numberLen = byteNum(number);
        int totalLen = byteNum(total);
        if (nameLen < 25) {
            printText += nameStr;
            for (int i = 0; i < 25 - nameLen; i++) {
                printText += takeUp;
            }
            nameLen -= byteNum(nameStr);
        } else {
            printText += nameStr.substring(0, 12);
            printText += takeUp;
            nameLen -= byteNum(nameStr.substring(0, 12));
            nameStr = nameStr.substring(12, nameStr.length());
        }

        if (priceLen < 9) {
            for (int i = 0; i < 9 - priceLen; i++)
                printText += takeUp;
            printText += price;
        } else {
            return "-2";
        }

        if (numberLen < 5) {
            for (int i = 0; i < 5 - numberLen; i++)
                printText += takeUp;
            printText += number;
        } else {
            return "-3";
        }

        if (totalLen < 9) {
            for (int i = 0; i < 9 - totalLen; i++)
                printText += takeUp;
            printText += total;
        } else {
            return "-4";
        }

        printText += "\n";
        while (nameLen > 0) {
            if (nameLen > 24) {
                printText += nameStr.substring(0, 12);
                nameLen -= byteNum(nameStr.substring(0, 12));
                nameStr = nameStr.substring(12, nameStr.length());
            } else {
                printText += nameStr;
                nameLen -= byteNum(nameStr);
            }
            printText += "\n";
        }
        return printText;
    }

    /**
     * 80mm的左右对称文本打印
     * <p>
     * 小字体一行打印位：48
     * 中字体一行打印位：24
     * 大字体一行打印位：16
     * 左右对称各占一半打印位
     *
     * @param textSize  文本大小  0：小  1：中  2：大 默认为小字体
     * @param leftText  左侧文本
     * @param rightText 右侧文本
     * @return
     */
    public static String eudipleural80Print(String textSize, String leftText, String rightText) {
        String printText = "";
        String takeUp = " ";                    // 填充符
        String lineBreak = "\n";                // 换行符
        int LINE_MAX_LEN = 48;                  // 一行的最大内容长度
        if (!TextUtils.isEmpty(textSize))
            if (textSize.equals("1"))
                LINE_MAX_LEN = 24;
            else if (textSize.equals("2"))
                LINE_MAX_LEN = 16;

        int SIDE_MAX_LEN = LINE_MAX_LEN / 2;    // 一侧的最大内容长度
        String leftStr = leftText;
        String rightStr = rightText;
        int leftLen = byteNum(leftStr);
        int rightLen = byteNum(rightStr);

        while ((leftLen > 0) || (rightLen > 0)) {
            if (leftLen == 0) {
                // 内容为空时铺满填充符
                for (int i = 0; i < SIDE_MAX_LEN; i++) {
                    printText += takeUp;
                }
            } else {
                // 判断显示的内容是否超出最大内容长度
                if (leftLen <= SIDE_MAX_LEN) {
                    printText += leftStr;
                    for (int i = 0; i < SIDE_MAX_LEN - leftLen; i++)
                        printText += takeUp;
                    leftLen -= byteNum(leftStr);
                } else {
                    int lenCount = 0;
                    int subCount = 0;
                    for (int i = 0; i < leftStr.length(); i++) {
                        lenCount += byteNum(String.valueOf(leftStr.charAt(i)));
                        if (lenCount > SIDE_MAX_LEN) {
                            subCount = i;
                            break;
                        }
                    }
                    printText += leftStr.substring(0, subCount);
                    if (lenCount % 2 != 0) printText += takeUp;
                    leftLen -= byteNum(leftStr.substring(0, subCount));
                    leftStr = leftStr.substring(subCount);
                }
            }

            if (rightLen == 0) {
                for (int i = 0; i < SIDE_MAX_LEN; i++) {
                    printText += takeUp;
                }
            } else {
                if (rightLen <= SIDE_MAX_LEN) {
                    for (int i = 0; i < SIDE_MAX_LEN - rightLen; i++)
                        printText += takeUp;
                    printText += rightStr;
                    rightLen -= byteNum(rightStr);
                } else {
                    int lenCount = 0;
                    int subCount = 0;
                    for (int i = 0; i < rightStr.length(); i++) {
                        lenCount += byteNum(String.valueOf(rightStr.charAt(i)));
                        if (lenCount > SIDE_MAX_LEN) {
                            subCount = i;
                            break;
                        }
                    }
                    printText += rightStr.substring(0, subCount);
                    if (lenCount % 2 != 0) printText += takeUp;
                    rightLen -= byteNum(rightStr.substring(0, subCount));
                    rightStr = rightStr.substring(subCount);
                }
            }

        }
        printText += lineBreak;
        return printText;
    }

    /**
     * 字符串转为字节集合
     *
     * @param hexStr
     * @return
     */
    public static List<Byte> hexStr2Str(String hexStr) {
        char[] hexs = hexStr.toCharArray();
        List<Byte> bytes = new ArrayList<>();
        int value;
        for (int i = 0; i < hexStr.length() / 2; i++) {
            value = ((charTobyte(hexs[2 * i]) << 4 | charTobyte(hexs[2 * i + 1])));
            bytes.add((byte) (value & 0xff));
        }
        return bytes;
    }

    /**
     * 获取占用打印位：汉字二个打印位、英文数字符号一个打印位
     *
     * @param str
     * @return
     */
    public static int byteNum(String str) {
        int m = 0;
        char arr[] = str.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            char c = arr[i];
            if ((c >= 0x0391 && c <= 0xFFE5))  //中文字符
                m = m + 2;
            else if ((c >= 0x0000 && c <= 0x00FF)) //英文字符
                m = m + 1;
        }
        return m;
    }

    /**
     * 字符转换为字节
     *
     * @param c
     * @return
     */
    private static byte charTobyte(char c) {
        switch (c) {
            case '0':
                return 0x00;
            case '1':
                return 0x01;
            case '2':
                return 0x02;
            case '3':
                return 0x03;
            case '4':
                return 0x04;
            case '5':
                return 0x05;
            case '6':
                return 0x06;
            case '7':
                return 0x07;
            case '8':
                return 0x08;
            case '9':
                return 0x09;
            case 'A':
            case 'a':
                return 0x0a;
            case 'B':
            case 'b':
                return 0x0b;
            case 'C':
            case 'c':
                return 0x0c;
            case 'D':
            case 'd':
                return 0x0d;
            case 'E':
            case 'e':
                return 0x0e;
            case 'F':
            case 'f':
                return 0x0f;
        }
        return 0;
    }


}
